﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using iTextSharp.text.pdf.qrcode;
using Transport.Core.Models.Customers;
using Transport.Infrastructure;
using Transport.Infrastructure.Mvc;
using Transport.Infrastructure.Security;
using Transport.Services.Infrastructure;
using Transport.Services.Parcels;
using Transport.Core.Models.Parcels;
using Transport.Services.Settings;
using Transport.Services.Customers;
using Transport.Services;
using Transport.Areas.Administrator.Models;
using Telerik.Web.Mvc;

namespace Transport.Areas.Administrator.Controllers
{
    [Authorize]
    public class ReportingController : ControllerBase<IParcelRepository, Parcel>
    {
        private readonly IStateProvinceRepository _stateProvinceRepository;
        private readonly ICustomerRepository _customerRepository;
        private readonly IParcelService _parcelService;
        private readonly ITrackingRepository _trackingRepository;
        private readonly IRegionRepository _regionRepository;
        public ReportingController(IUnitOfWork unitOfWork, IParcelRepository repository,
                                IStateProvinceRepository stateProvinceRepository, ICustomerRepository customerRepository,
                                IParcelService parcelService,IRegionRepository regionRepository,
                                ITrackingRepository trackingRepository)
            : base(repository, unitOfWork)
        {
            _stateProvinceRepository = stateProvinceRepository;
            _customerRepository = customerRepository;
            _parcelService = parcelService;
            _trackingRepository = trackingRepository;
            _regionRepository = regionRepository;
        }
        //
        // GET: /Administrator/Reporting/

        public ActionResult ParcelReporting()
        {
            var stateProvinces = _stateProvinceRepository.Search("").ToList();
            var regions = _regionRepository.GetAll().ToList();
            var model = new ParcelReportModel
            {
                StateProvinces = stateProvinces,
                Regions = regions,
            };

            return View(model);
        }

        [GridAction]
        public ActionResult GetParcelReporting(ParcelReportFilterModel model)
        {
            //Default get all
            IQueryable<ParcelReportModel> query;
            var dateReport = DateTime.Today;
            var isAllDate = true;
            var listChecked = new int[1];
            var isAllDeliverTo = true;
            //Filter by deliver to
            if (model.ListChecks != null && model.ListChecks.Count() > 0)
            {
                listChecked = model.ListChecks;
                isAllDeliverTo = false;
            }
            //Filter by date
            if (model.DateReport.HasValue)
            {
                dateReport = model.DateReport.Value.Date;
                isAllDate = false;
            }
            var dateAfter = dateReport.AddDays(1);
            if (model.IsReportByRegion)
            {
                query = from x in Repository.GetAll()
                        join p in _stateProvinceRepository.Search("") on x.DeliverToId equals p.StateProvinceId
                        where (x.DeliverFromId == model.DeliverFrom || model.DeliverFrom == 0) &&
                                ((x.DateOfSending >= dateReport && x.DateOfSending < dateAfter) || isAllDate) &&
                                (isAllDeliverTo)
                        orderby x.ParcelId descending
                        select new ParcelReportModel
                        {
                            AddressTo = x.ToAddress,
                            CustomerName = x.Customer.CustomerName,
                            No = x.ParcelId,
                            PaymentType = x.PaymentType,
                            TrackingNumbers = x.TrackingNumbers,
                            Weight = x.TotalWeight
                        };
                
            }
            else
            {
                query = from x in Repository.GetAll()
                        join p in _stateProvinceRepository.GetAll() on x.DeliverToId equals p.StateProvinceId
                        where (x.DeliverFromId == model.DeliverFrom || model.DeliverFrom == 0) &&
                                ((x.DateOfSending >= dateReport && x.DateOfSending < dateAfter) || isAllDate) &&
                                (listChecked.Contains(p.StateProvinceId) || isAllDeliverTo)
                        orderby x.ParcelId descending
                        select new ParcelReportModel
                        {
                            AddressTo = x.ToAddress,
                            CustomerName = x.Customer.CustomerName,
                            No = x.ParcelId,
                            PaymentType = x.PaymentType,
                            TrackingNumbers = x.TrackingNumbers,
                            Weight = x.TotalWeight
                        };
            }
            //save session to download
            Session["QueryDownloadParcelReporting"] = query;
            Session["ParcelReportingDate"] = model.DateReport.HasValue ? model.DateReport.Value.ToString("dd/MM/yyyy") : "Tất cả";
            if (model.DeliverFrom == 0)
            {
                Session["ParcelReportingFrom"] = "Tất cả";
            }
            else
            {
                var from = _stateProvinceRepository.GetAll().Where(p => p.StateProvinceId == model.DeliverFrom).Select(p => p.StateProvinceName).FirstOrDefault();
                Session["ParcelReportingFrom"] = from;
            }
            if (model.ListChecks != null && model.ListChecks.Count() > 0)
            {
                if (model.IsReportByRegion)
                {
                    var to = _regionRepository.GetAll().Where(p => listChecked.Contains(p.RegionId)).Select(p => p.RegionName).ToList();
                    Session["ParcelReportingTo"] = string.Join(";", to);
                }
                else
                {
                    var to = _stateProvinceRepository.GetAll().Where(p => listChecked.Contains(p.StateProvinceId)).Select(p => p.StateProvinceName).ToList();
                    Session["ParcelReportingTo"] = string.Join(";", to);
                }
            }
            else
            {
                Session["ParcelReportingTo"] = "Tất cả";
            }
            var gridModel = new GridModel<ParcelReportModel>
            {
                Data = query
            };
            return new JsonResult
            {
                Data = gridModel
            };
        }

        [OutputCache(NoStore = true, Duration = 0, VaryByParam = "*")]
        public ActionResult DownloadParcelReporting()
        {
            var query = (IQueryable<ParcelReportModel>)Session["QueryDownloadParcelReporting"];
            var from = (string)Session["ParcelReportingFrom"];
            var to = (string)Session["ParcelReportingTo"];
            var reportDate = (string)Session["ParcelReportingDate"];
            var fileName = string.Format("Reporting_{0}", DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss"));
            return PdfResult(_parcelService.DownloadParcelReporting(query.ToList(), from, to, reportDate),fileName);
        }

        public ActionResult ParcelCustomerReporting()
        {
            var customers = _customerRepository.Search("").Where(p => p.MyOfficeId == WorkContext.MyOfficeId).ToList();
            customers.Insert(0, new Customer
            {
                CustomerName = "Khách lẻ",
                CustomerId = -1
            });
            var model = new ParcelCustomerReportModel
            {
                Customers = customers,
                FromDate = DateTime.Now,
                ToDate = DateTime.Now
            };

            return View(model);
        }

        [GridAction]
        public ActionResult GetParcelCustomerReporting(ParcelCustomerReportModel model)
        {
            model.ToDate = model.ToDate.AddDays(1);
            var query = from x in Repository.GetAll()
                    join p in _stateProvinceRepository.GetAll() on x.DeliverToId equals p.StateProvinceId
                        where ((x.CustomerId == model.CustomerId || (model.CustomerId == -1 && x.CustomerId == null) || (model.CustomerId == null))
                        && (x.PaymentType == model.PaymentType || (model.PaymentType == 0))
                        && x.IsApproval
                        && x.MyOfficeId == WorkContext.MyOfficeId
                        && x.DateOfSending >= model.FromDate
                        && x.DateOfSending <= model.ToDate)
                    orderby x.CustomerId, x.ParcelId descending
                    select new ParcelCustomerReportModel
                    {
                        No = x.ParcelId,
                        DateOfSending = x.DateOfSending,
                        TrackingNumbers = x.TrackingNumbers,
                        DeliverTo = p.StateProvinceName,
                        Weight = x.TotalWeight,
                        Cost = x.TotalCost
                    };
            //Chỉ tạo bảng kê cho những bưu phẩm đã được thanh toán - đối với bảng kê tiền mặt và thu hộ
            if (model.PaymentType == (int)PaymentTypes.EnumPaymentTypes.Cash || model.PaymentType == (int)PaymentTypes.EnumPaymentTypes.Collection)
            {
                query.Where(p => p.Collected);
            }
            var gridModel = new GridModel<ParcelCustomerReportModel>
            {
                Data = query
            };
            return new JsonResult
            {
                Data = gridModel
            };
        }

        [OutputCache(NoStore = true, Duration = 0, VaryByParam = "*")]
        [HttpPost]
        public ActionResult ParcelCustomerReporting(ParcelCustomerReportModel model)
        {
            model.ToDate = model.ToDate.AddDays(1);
            var query = from x in Repository.GetAll()
                        join p in _stateProvinceRepository.GetAll() on x.DeliverToId equals p.StateProvinceId
                        where ((x.CustomerId == model.CustomerId || (model.CustomerId == -1 && x.CustomerId == null) || (model.CustomerId == null))
                        && (x.PaymentType == model.PaymentType || (model.PaymentType == 0))
                        && x.IsApproval
                        && x.MyOfficeId == WorkContext.MyOfficeId
                        && x.DateOfSending >= model.FromDate
                        && x.DateOfSending <= model.ToDate)
                        orderby x.CustomerId, x.ParcelId descending
                        select new ParcelCustomerReportModel
                        {
                            No = x.ParcelId,
                            DateOfSending = x.DateOfSending,
                            TrackingNumbers = x.TrackingNumbers,
                            DeliverTo = p.StateProvinceName,
                            Weight = x.TotalWeight,
                            Cost = x.TotalCost,
                            CustomerId = x.CustomerId,
                            Collected = x.Collected,
                            Note = x.Note
                        };
            //Chỉ tạo bảng kê cho những bưu phẩm đã được thanh toán - đối với bảng kê tiền mặt và thu hộ
            if (model.PaymentType == (int)PaymentTypes.EnumPaymentTypes.Cash || model.PaymentType == (int)PaymentTypes.EnumPaymentTypes.Collection)
            {
                query.Where(p => p.Collected);
            }
            var fromDate = String.Format("{0:dd/MM/yyyy}", model.FromDate);
            var toDate = String.Format("{0:dd/MM/yyyy}", model.ToDate);
            List<Customer> customers;
            if (model.CustomerId == -1)
            {
                customers = new List<Customer>()
                {
                    new Customer
                    {
                        CustomerId = -1,
                        CustomerName = "Khách lẻ"
                    }
                };
            }
            else if(model.CustomerId == null)
            {
                customers = _customerRepository.Search("").Where(p => p.MyOfficeId == WorkContext.MyOfficeId).ToList();
                customers.Insert(0, new Customer
                {
                    CustomerId = -1,
                    CustomerName = "Khách lẻ"
                });
            }
            else
            {
                var customer = _customerRepository.GetById(model.CustomerId);
                customers = new List<Customer>()
                {
                    customer
                };
            }
            var fileName = string.Format("Reporting_{0}", DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss"));
            return PdfResult(_parcelService.DownloadParcelCustomerReporting(query.ToList(), fromDate, toDate, customers, model.PaymentType, WorkContext.MyOfficeId), fileName);
        }
    }
}
